<?php

namespace app\api\controller;

use app\common\controller\Api;
use think\Db;
use think\facade\Log;

/**
 * 网络监测接口
 */
class Nqm extends Api
{

    //如果$noNeedLogin为空表示所有接口都需要登录才能请求
    //如果$noNeedRight为空表示所有接口都需要验证权限才能请求
    //如果接口已经设置无需登录,那也就无需鉴权了
    //
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = [];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['quality', 'app', 'link','apps','app_detail'];

    public function getUserConfig(){
        $userinfo = $this->auth->getUserinfo();
        $id = $userinfo['id'];
        $probe = Db::name('user_config')->where('user_id',$id)->value('probe');
        // dump($probe);exit;
        if(!$probe){
            $this->error('请先配置探测接口');
        }
        $probe_arr = json_decode($probe,true); //格式化一下
        $mission = $probe_arr['mission'];
        return $mission;
    }
    public function request_nqm($data_string, $snap='', $fix_url=''){
        $userinfo = $this->auth->getUserinfo();
        $id = $userinfo['id'];
        $probe = Db::name('user_config')->where('user_id',$id)->value('probe');
        // dump($probe);exit;
        if(!$probe){
            $this->error(__('Please configure the probe interface'));
        }
        $probe_arr = json_decode($probe,true); //格式化一下
        if( !(isset($probe_arr['url']) && $probe_arr['url']) ){
            $this->error(__('Please configure the probe interface : url'));
        }

        $result = array();
        if($fix_url){
          $url = $probe_arr['url'].$fix_url;
        }else{
          $url = $probe_arr['url'].config('base_url');
        }
        // dump($url);exit;
        Log::record(microtime().'发送拨测地址：'.$url,'API');
        Log::record(microtime().'发送拨测参数：'.$data_string,'API');
        //发请求拿数据
        $curlopt = array(
            CURLOPT_HTTPHEADER=>array ('Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen ( $data_string ) ),
            CURLOPT_TIMEOUT=>config('quality')['timeout'],
        );
        $data = curl_post($url, $data_string, $curlopt);
        // dump($data);exit;
        Log::record(microtime().'拨测接口返回：'.$data,'API');
        if(!$data){
            if($snap != 'snap'){
                $this->error('nqm接口异常');
            }
        }
        if(!is_json($data)){
            if($snap != 'snap'){
                $this->error('nqm接口返回的不是JSON格式');
            }
        }
        $arr = json_decode($data,true);
        if($arr['code'] == 0){
            if($snap != 'snap'){
                $this->error($arr['msg']);
            }
        }
        $arr = $arr['data'];
        if($snap == 'all'){
          $result = $arr;
        }else{
          $result = $arr['aggregations']['2']['buckets'];
        }
        if( ! ($result && count($result)>0 ) ){
            if(!$snap){
                $this->error('nqm接口数据为空');
            }
        }
        return $result;
    }
    //首页-综合质量：求出每类action当天的平均质量分，要综合天路云配置各类的比例
    public function quality(){
        $starttime_es = (time()-30*60).'000'; //最近30分钟
        $endtime_es = time().'000';

        $mission = $this->getUserConfig();
        $missionIds = array();
        $missionIds_str = '';
        foreach ($mission as $key => $value) {
            foreach ($value as $key2 => $value2) {
                $missionIds[] = trim($value2['missionid']);
                $missionIds_str .= '{
                    "match_phrase": {
                      "missionId": {
                        "query": "'.trim($value2['missionid']).'"
                      }
                    }
                  },';
            }
        }
        //去掉最后一个逗号
        if($missionIds_str){
          $missionIds_str = substr($missionIds_str, 0, strlen($missionIds_str)-1);
        }

        $data_string = '{
          "aggs": {
            "2": {
              "terms": {
                "field": "action.keyword",
                "size": 10,
                "order": {
                  "1": "desc"
                }
              },
              "aggs": {
                "1": {
                  "avg": {
                    "field": "qualityScore"
                  }
                }
              }
            }
          },
          "size": 0,
          "_source": {
            "excludes": []
          },
          "stored_fields": [
            "*"
          ],
          "script_fields": {},
          "docvalue_fields": [],
          "query": {
            
            "bool": {
              "must": [
                {
                  "match_all": {}
                },
                {
                  "range": {
                    "testTime": {
                      "gte": '.$starttime_es.',
                      "lte": '.$endtime_es.',
                      "format": "epoch_millis"
                    }
                  }
                }
              ],
              "filter": [{
                "range": {
                  "qualityScore": {
                    "gt": "0"
                  }
                }
              }],
              "should": [
                '.$missionIds_str.'
              ],
              "minimum_should_match": 1,
              "must_not": []
            }
          }
        }';


        $result = $this->request_nqm($data_string, 'snap');
        // dump($result);exit;
        $quality = '-';
        if(is_array($result) && count($result)>0){
           foreach ($result as $key => $value) {
              $action = $value['key'];
              $actions = config('actions');
              if( isset($actions[$action]) ){
                  $propertyname = $actions[$action];
              }else{
                  continue;
              }
              $score = $value[1]['value'];
              if($score == -1){
                  continue;
              }
              $quality = floatval($quality) + $score*config('quality')['propertyname_percent'][$propertyname];
              
          }
        }
        if($quality == '-'){
            return -1;
        }else{
            return round($quality,0);
        }
    }
    //首页-应用质量：求出所有应用的质量分均值，要综合天路云配置的应用
    public function app_bak(){
        $starttime_es = (time()-30*60).'000';
        $endtime_es = time().'000';
        $action = "get_QualityLinkRouteResult_FW"; //除了链路，更外四类的平均分
        
        $mission = $this->getUserConfig();
        $missionIds = array();
        $missionIds_str = '';
        foreach ($mission as $key => $value) {
            if($key != 'basedlink'){
                foreach ($value as $key2 => $value2) {
                    $missionIds[] = trim($value2['missionid']);
                    $missionIds_str .= '{
                        "match_phrase": {
                          "missionId": {
                            "query": "'.trim($value2['missionid']).'"
                          }
                        }
                      },';
                }
            }
        }
        //去掉最后一个逗号
        if($missionIds_str){
          $missionIds_str = substr($missionIds_str, 0, strlen($missionIds_str)-1);
        }

        $data_string = '{
          "aggs": {
            "2": {
              "terms": {
                "field": "targetName.keyword",
                "size": 100,
                "order": {
                  "1": "desc"
                }
              },
              "aggs": {
                "1": {
                  "avg": {
                    "field": "qualityScore"
                  }
                }
              }
            }
          },
          "size": 0,
          "_source": {
            "excludes": []
          },
          "stored_fields": [
            "*"
          ],
          "script_fields": {},
          "docvalue_fields": [],
          "query": {
            "bool": {
              "must": [
                {
                  "match_all": {}
                },
                {
                  "range": {
                    "testTime": {
                      "gte": '.$starttime_es.',
                      "lte": '.$endtime_es.',
                      "format": "epoch_millis"
                    }
                  }
                }
              ],
              "filter": [{
                "range": {
                  "qualityScore": {
                    "gt": "0"
                  }
                }
              }],
              "should": [
                '.$missionIds_str.'
              ],
              "minimum_should_match": 1,
              "must_not": [
                {
                  "match_phrase": {
                    "action": {
                      "query": "'.$action.'"
                    }
                  }
                }
              ]
            }
          }
        }';

        $result = $this->request_nqm($data_string, 'snap');

        $all_score = array();
        // dump($result);exit;
        foreach ($result as $key => $value) {
            $score = $value[1]['value'];
            $app = $value['key'];
            $all_score[$app] = $score;
        }
        // dump($all_score);exit;
        $score = $this->getDbAppScore($all_score);
        // $score = $all_score; //测试用
        // dump($score);exit;
        $row = array(
            'score'=> -1,
            'appqualitys'=>'-',
        );
        if(count($score) > 0 ){
            $avg = round(array_sum($score)/count($score),2);
            $row['score']=$avg;
            $row['appqualitys']=$this->get_level('应用质量', $avg);
        }
        return $row;
    }
    //首页-应用质量：求出所有应用的质量分均值，不管后台配置的应用
    public function app(){
        $starttime_es = (time()-30*60).'000';
        $endtime_es = time().'000';
        $action = "get_QualityLinkRouteResult_FW"; //除了链路，更外四类的平均分
        
        $mission = $this->getUserConfig();
        $missionIds = array();
        $missionIds_str = '';
        foreach ($mission as $key => $value) {
            if($key != 'basedlink'){
                foreach ($value as $key2 => $value2) {
                    $missionIds[] = trim($value2['missionid']);
                    $missionIds_str .= '{
                        "match_phrase": {
                          "missionId": {
                            "query": "'.trim($value2['missionid']).'"
                          }
                        }
                      },';
                }
            }
        }
        //去掉最后一个逗号
        if($missionIds_str){
          $missionIds_str = substr($missionIds_str, 0, strlen($missionIds_str)-1);
        }

        $data_string = '{
          "aggs": {
            "2": {
              "avg": {
                "field": "qualityScore"
              }
            }
          },
          "size": 0,
          "_source": {
            "excludes": []
          },
          "stored_fields": [
            "*"
          ],
          "script_fields": {},
          "docvalue_fields": [],
          "query": {
            "bool": {
              "must": [
                {
                  "match_all": {}
                },
                {
                  "range": {
                    "testTime": {
                      "gte": '.$starttime_es.',
                      "lte": '.$endtime_es.',
                      "format": "epoch_millis"
                    }
                  }
                }
              ],
              "filter": [{
                "range": {
                  "qualityScore": {
                    "gt": "0"
                  }
                }
              }],
              "should": [
                '.$missionIds_str.'
              ],
              "minimum_should_match": 1,
              "must_not": [
                {
                  "match_phrase": {
                    "action": {
                      "query": "'.$action.'"
                    }
                  }
                }
              ]
            }
          }
        }';

        $result = $this->request_nqm($data_string, 'all');
        if(isset($result["aggregations"][2]['value']) && $result["aggregations"][2]['value']){
          $score = $result["aggregations"][2]['value'];
          $level = $this->get_level('应用质量', $score);
        }else{
          $score = -1;
          $level = '-';
        }
        return array(
          'score'=>$score,
          'appqualitys'=>$level
        );
    }
    //某类action下的质量分，按时间段聚合
    public function link($snap=''){
        if($snap == 'app'){
            return $this->app();
        }
        //处理参数
        $propertyname = $this->request->post('propertyname');
        if(!$propertyname){
            $this->error(__('Missed parameters'));
        }
        if(!in_array($propertyname, config('quality')['propertyname']) ){ 
            $this->error(__('Invalid parameters'));
        }

        $starttime = $this->request->post('starttime');
        if(!$starttime){
            if($propertyname == 'basedlinkdetails' || $propertyname == 'basedlinkdetails_sort'){
              $starttime = date('Y-m-d 00:00:00');
            }else{
              $starttime = date('Y-m-d H:i:s',time()-24*60*60);
            }
        }
        $endtime = $this->request->post('endtime');
        if(!$endtime){
            $endtime = date('Y-m-d H:i:s');
        }

        $gradename = $this->request->post('gradename');
        if(!$gradename){
            $gradename = '5分钟';
        }
        $gradename_arr = array(
          '5分钟'=>'5m',
          '半小时'=>'30m',
          '1小时'=>'1h',
          '4小时'=>'4h',
          '每天'=>'1d',
          '每周'=>'1w',
          '每月'=>'1M',
        );
        $gradename_es = isset($gradename_arr[$gradename]) ? $gradename_arr[$gradename] : '5m';
        $starttime_es = strtotime($starttime).'000';
        $endtime_es = strtotime($endtime).'000';


        if($propertyname == 'basedlinkdetails_sort'){
            $typenum = $this->request->post('typenum');
            $appnum = $this->request->post('appnum');
            return $this->app_shiyan($typenum, $appnum, $starttime_es, $endtime_es);
        }

        $apptype = $this->request->post('apptype');
        $appname = $this->request->post('appname');
        if($propertyname == 'basedlinkdetails'){
            if($apptype && $appname){
              return $this->app_shiyan_detail($apptype, $appname, $gradename_es, $starttime_es, $endtime_es);
            }else{
              return $this->all_app_detail();
            }
        }


        $action = array_flip(config('actions'))[$propertyname];

        $mission = $this->getUserConfig();
        $missionIds = array();
        $missionIds_str = '';
        foreach ($mission as $key => $value) {
            if($key == $propertyname){
                foreach ($value as $key2 => $value2) {
                    $missionIds[] = trim($value2['missionid']);
                    $missionIds_str .= '{
                        "match_phrase": {
                          "missionId": {
                            "query": "'.trim($value2['missionid']).'"
                          }
                        }
                      },';
                }
            }
        }
        //去掉最后一个逗号
        if($missionIds_str){
          $missionIds_str = substr($missionIds_str, 0, strlen($missionIds_str)-1);
        }
        $data_string = '{
          "aggs": {
            "2": {
               "date_histogram": {
                    "field": "testTime",
                    "interval": "'.$gradename_es.'",
                    "time_zone": "Asia/Shanghai",
                    "min_doc_count": 1
                },
                "aggs": {
                    "1": {
                        "avg": {
                            "field": "qualityScore"
                        }
                    }
                }
            }
          },
          "size": 0,
          "_source": {
            "excludes": []
          },
          "stored_fields": [
            "*"
          ],
          "script_fields": {},
          "docvalue_fields": [],
          "query": {
            "bool": {
              "must": [
                {
                  "match_all": {}
                },
                {
                  "range": {
                    "testTime": {
                      "gte": '.$starttime_es.',
                      "lte": '.$endtime_es.',
                      "format": "epoch_millis"
                    }
                  }
                },
                {
                  "match_phrase": {
                    "action": {
                      "query": "'.$action.'"
                    }
                  }
                }
              ],
              "filter": [{
                "range": {
                  "qualityScore": {
                    "gt": "0"
                  }
                }
              }],
              "should": [
                '.$missionIds_str.'
              ],
              "minimum_should_match": 1,
              "must_not": []
            }
          }
        }';
        
        $result = $this->request_nqm($data_string);
        // dump($result);exit;
        $quality = array();
        $quality['total'] = count($result);
        foreach ($result as $key => $value) {
            $item = array();
            $item['qualityScore'] = (double)round($value[1]['value'], 2);
            $item['timeInterval'] = date('Y-m-d H:i:s',$value['key']/1000);
            $quality['item'][] = $item;
        }
        return $this->success('成功', array($quality)); //再包一层，之前有链路id，所以是两层
    }
    //某类action下的质量分，按时间段聚合，带出口
    public function link_export(){
        //处理参数
        $propertyname = $this->request->post('propertyname');
        if(!$propertyname){
            $this->error(__('Missed parameters'));
        }
        if(!in_array($propertyname, config('quality')['propertyname']) ){ 
            $this->error(__('Invalid parameters'));
        }

        $starttime = $this->request->post('starttime');
        if(!$starttime){
              $starttime = date('Y-m-d H:i:s',time()-24*60*60);
        }
        $endtime = $this->request->post('endtime');
        if(!$endtime){
            $endtime = date('Y-m-d H:i:s');
        }

        $gradename = $this->request->post('gradename');
        if(!$gradename){
            $gradename = '1小时';
        }
        $gradename_arr = array(
          '5分钟'=>'5m',
          '半小时'=>'30m',
          '1小时'=>'1h',
          '4小时'=>'4h',
          '每天'=>'1d',
          '每周'=>'1w',
          '每月'=>'1M',
        );
        $gradename_es = isset($gradename_arr[$gradename]) ? $gradename_arr[$gradename] : '5m';
        $starttime_es = strtotime($starttime).'000';
        $endtime_es = strtotime($endtime).'000';

        $action = array_flip(config('actions'))[$propertyname];

        $mission = $this->getUserConfig();
        $missionIds = array();
        $missionIds_str = '';
        foreach ($mission as $key => $value) {
            if($key == $propertyname){
                foreach ($value as $key2 => $value2) {
                    $missionIds[] = trim($value2['missionid']);
                }
            }
        }
        $missionIds_str = implode(',', $missionIds);
        $data = array(
          'action'=>$action,
          'starttime'=>$starttime,
          'endtime'=>$endtime,
          'gradename'=>$gradename_es,
          'missionId'=> $missionIds_str
        );
        // dump($data);exit;
        $data_string = json_encode($data);
        
        $url = config('link_export_url');
        // dump($url);exit;
        $result = $this->request_nqm($data_string, 'all', $url);
        // dump($result);exit;
        $quality = array();
        if(is_array($result) && count($result) >0){
          foreach ($result as $key => $value) {
            $one = array();
            $one['export'] = $key;
            foreach ($value[2]['buckets'] as $key2 => $value2) {
              $item = array();
              $item['qualityScore'] = (double)round($value2[1]['value'], 2);
              $item['timeInterval'] = date('Y-m-d H:i:s',$value2['key']/1000);
              $one['item'][] = $item;
            }
            $one['total'] = count($one['item']);
            $quality[] = $one; 
          }
        }
        // dump($quality);exit;
        return $this->success('成功', $quality);
    }
    //某类质量页
    public function type_quality($propertyname=''){
        //处理参数
        $starttime_es = (time()-30*60).'000';
        $endtime_es = time().'000';

        if(!$propertyname){
          $propertyname = $this->request->post('propertyname');
        }
        if(!$propertyname){
          $this->error('缺少任务名参数');
        }
        $actions = array_flip(config('actions'));
        $action = isset($actions[$propertyname]) ? $actions[$propertyname] : '';
        if(!$action){
          $this->error('不支持的任务名');
        } 

        $mission = $this->getUserConfig();
        $missionIds = array();
        $missionIds_str = '';
        foreach ($mission as $key => $value) {
            if($key == $propertyname){
                foreach ($value as $key2 => $value2) {
                    $missionIds[] = trim($value2['missionid']);
                    $missionIds_str .= '{
                        "match_phrase": {
                          "missionId": {
                            "query": "'.trim($value2['missionid']).'"
                          }
                        }
                      },';
                }
            }
        }
        //去掉最后一个逗号
        if($missionIds_str){
          $missionIds_str = substr($missionIds_str, 0, strlen($missionIds_str)-1);
        }
        $data_string = '{
          "aggs": {
            "2": {
                "avg": {
                    "field": "qualityScore"
                }
            }
          },
          "size": 0,
          "_source": {
            "excludes": []
          },
          "stored_fields": [
            "*"
          ],
          "script_fields": {},
          "docvalue_fields": [],
          "query": {
            "bool": {
              "must": [
                {
                  "match_all": {}
                },
                {
                  "range": {
                    "testTime": {
                      "gte": '.$starttime_es.',
                      "lte": '.$endtime_es.',
                      "format": "epoch_millis"
                    }
                  }
                },
                {
                  "match_phrase": {
                    "action": {
                      "query": "'.$action.'"
                    }
                  }
                }
              ],
              "filter": [{
                "range": {
                  "qualityScore": {
                    "gt": "0"
                  }
                }
              }],
              "should": [
                '.$missionIds_str.'
              ],
              "minimum_should_match": 1,
              "must_not": []
            }
          }
        }';
        
        $result = $this->request_nqm($data_string, 'all');
        // dump($result);exit;
        if(isset($result["aggregations"][2]['value']) && $result["aggregations"][2]['value']){
          $score = round($result["aggregations"][2]['value'],2);
        }else{
          $score = -1;
        }
        if($this->request->post('propertyname')){
          $this->success('', $score);
        }else{
          return $score;
        }
    }
    //应用质量：所有应用下的当天的平均时延；要综合天路云配置的应用
    public function app_shiyan($typenum, $appnum, $starttime_es, $endtime_es){
        if(!$typenum){
            $typenum = config('quality')['basedlinkdetails_sort_type_num'];
        }
        if(!$appnum){
            $appnum = config('quality')['basedlinkdetails_sort_app_num'];
        }
        
        $mission = $this->getUserConfig();
        $missionIds = array();
        $missionIds_str = '';
        foreach ($mission as $key => $value) {
            // if($key == 'basedlink'){
                foreach ($value as $key2 => $value2) {
                    $missionIds[] = trim($value2['missionid']);
                    $missionIds_str .= '{
                        "match_phrase": {
                          "missionId": {
                            "query": "'.trim($value2['missionid']).'"
                          }
                        }
                      },';
                }
            // }
        }
        //去掉最后一个逗号
        if($missionIds_str){
          $missionIds_str = substr($missionIds_str, 0, strlen($missionIds_str)-1);
        }

        $data_string = '{
           "aggs": {
            "2": {
              "terms": {
                "field": "action.keyword",
                "size": 10
              },
              "aggs": {
                "targetName": {
                  "terms": {
                    "field": "targetName.keyword",
                    "size": 100,
                    "order": {
                      "qualityScore": "desc"
                    }
                  },
                  "aggs": {
                    "netWorkDelay": {
                      "avg": {
                        "field": "netWorkDelay"
                      }
                    },
                    "qualityScore": {
                      "avg": {
                        "field": "qualityScore"
                      }
                    }
                  }
                }
              }
            }
          },
          "size": 0,
          "_source": {
            "excludes": []
          },
          "stored_fields": [
            "*"
          ],
          "script_fields": {},
          "docvalue_fields": [],
          "query": {
            "bool": {
              "must": [
                {
                  "match_all": {}
                },
                {
                  "range": {
                    "testTime": {
                      "gte": '.$starttime_es.',
                      "lte": '.$endtime_es.',
                      "format": "epoch_millis"
                    }
                  }
                }
              ],
              "filter": [{
                "range": {
                  "qualityScore": {
                    "gt": "0"
                  }
                }
              }],
              "should": [
                '.$missionIds_str.'
              ],
              "minimum_should_match": 1,
              "must_not": []
            }
          }
        }';
        // dump($data_string);exit;
        $result = $this->request_nqm($data_string);
        // dump($result);exit;

        $name_type = $this->get_apps('name_type');
        $data_arr = array();
        $actions = config('actions');
        $type_action = array_flip(config('type_action'));
        foreach ($result as $key => $value) {
          $action = $value['key'];
          $type = $type_action[$action];
          foreach ($value['targetName']['buckets'] as $key2 => $value2) {
            $netWorkDelay = $value2['netWorkDelay']['value'];
            $qualityScore = $value2['qualityScore']['value'];
            $name = $value2['key'];
            // $type = $this->get_type_icon($name, 'type', $name_type);
            // if(!$type){
                // continue;
            // }
            // $data_arr[$type][$name] = $netWorkDelay;
            $data_arr[$type][$name] = $qualityScore;
          } 
        }
        // dump($data_arr);exit;

        //格式化$data_arr，取4个大类，每大类4个小类 取数据排序字段
        $data_arr = $this->format_sort($data_arr);
        // dump($data_arr);exit;
        //格式化
        $temp_arr = array();
        $i = 0;
        foreach ($data_arr as $key => $value) {
            $temp = array();
            $temp['name'] = $key;
            $temp['icon'] = request()->domain().$this->apptype($key);
            if($i++ > ($typenum-1) ){ 
                break;
            }
            $j = 0;
            foreach ($value as $key2 => $value2) {
                if($j++ > ($appnum-1) ){ 
                    break;
                }
                // $icon = $this->get_type_icon($key2, 'icon', $name_type);
                // if($icon){
                //     $temp['icon'] = request()->domain().$icon;
                // }else{
                //     $temp['icon'] = '';
                // }
                $temp_temp = array();
                $temp_temp['name'] = $key2;
                $temp_temp['value'] = round($value2,2);
                $temp_temp['level'] = $this->get_level('应用质量', $value2);
                $temp_temp['qualityScore'] = round($data_arr[$key][$key2],2);
                $temp['list'][] = $temp_temp;
            }
            $temp_arr[] = $temp;
        }
        $data_arr = $temp_arr;  
        $this->success('成功', $data_arr);
    }
    //应用质量详情：单个应用的时延、抖动、丢包率按时间段聚合， 要综合天路云配置的应用
    public function app_shiyan_detail($apptype, $appname, $gradename_es, $starttime_es, $endtime_es){
        if(!$apptype){
            $this->error(__('Missed parameters'));
        }
        if(!$appname){
            $this->error(__('Missed parameters'));
        }
        $name_type = $this->get_apps('name_type');
        $is_valid_app = $this->has_app($appname, $apptype, $name_type);
        if(!$is_valid_app){
            $this->error(__('Invalid parameters'));
        }

        $action = isset(config('type_action')[$apptype]) ? config('type_action')[$apptype] : '';
        // dump(config('type_action'));exit;
        $type = isset(config('actions')[$action]) ? config('actions')[$action] : '';
        if(!$action || !$type){
          $this->error('未知的类型');
        }
        $targetName = $appname;

        $mission = $this->getUserConfig();
        $missionIds = array();
        $missionIds_str = '';
        foreach ($mission as $key => $value) {
          if($type == $key){
            foreach ($value as $key2 => $value2) {
                $missionIds[] = trim($value2['missionid']);
                $missionIds_str .= '{
                    "match_phrase": {
                      "missionId": {
                        "query": "'.trim($value2['missionid']).'"
                      }
                    }
                  },';
            }
          }
        }
        //去掉最后一个逗号
        if($missionIds_str){
          $missionIds_str = substr($missionIds_str, 0, strlen($missionIds_str)-1);
        }

        $data_string = '{
          "aggs": {
            "2": {
               "date_histogram": {
                    "field": "testTime",
                    "interval": "'.$gradename_es.'",
                    "time_zone": "Asia/Shanghai",
                    "min_doc_count": 1
                },
                "aggs": {
                    "netWorkDelay": {
                      "avg": {
                        "field": "netWorkDelay"
                      }
                    }, 
                    "shaking": {
                      "avg": {
                        "field": "shaking"
                      }
                    },
                    "equipmentSuccessRate": {
                      "avg": {
                        "field": "equipmentSuccessRate"
                      }
                    }
                }
            }
          },
          "size": 0,
          "_source": {
            "excludes": []
          },
          "stored_fields": [
            "*"
          ],
          "script_fields": {},
          "docvalue_fields": [],
          "query": {
            "bool": {
              "must": [
                {
                  "match_all": {}
                },
                {
                  "range": {
                    "testTime": {
                      "gte": '.$starttime_es.',
                      "lte": '.$endtime_es.',
                      "format": "epoch_millis"
                    }
                  }
                }
                ,{
                  "match_phrase": {
                    "action": {
                      "query": "'.$action.'"
                    }
                  }
                },{
                  "match_phrase": {
                    "targetName": {
                      "query": "'.$appname.'"
                    }
                  }
                }
              ],
              "filter": [{
                "range": {
                  "qualityScore": {
                    "gt": "0"
                  }
                }
              }],
              "should": [
                '.$missionIds_str.'
              ],
              "minimum_should_match": 1,
              "must_not": []
            }
          }
        }';

        $result = $this->request_nqm($data_string);
        // dump($result);exit;
        $arr = array();
        $shaking = array();
        $netWorkDelay = array();
        $packageLoss = array();
        foreach ($result as $key => $value) {
            $s_item = array();
            $s_item['timeInterval'] = date('Y-m-d H:i:s', $value['key']/1000);
            $s_item['value'] = (double)round($value['shaking']['value'],2);
            $shaking[] = $s_item;

            $n_item = array();
            $n_item['timeInterval'] = $s_item['timeInterval'];
            $n_item['value'] = (double)round($value['netWorkDelay']['value'],2);
            $netWorkDelay[] = $n_item;

            $p_item = array();
            $p_item['timeInterval'] = $s_item['timeInterval'];
            $p_item['value'] = (double)round(100 - $value['equipmentSuccessRate']['value'],2);
            $packageLoss[] = $p_item;
        }
        $arr['shaking'] = $shaking;
        $arr['netWorkDelay'] = $netWorkDelay;
        $arr['packageLoss'] = $packageLoss;
        $this->success('成功', $arr);
    }
    //应用质量详情2：单个应用的一段时间内的详情，各个指标取平均数
    public function app_detail(){
      $starttime = $this->request->post('starttime');
      if(!$starttime){  
        $starttime = date('Y-m-d H:i:s',time()-24*60*60);
      }
      $endtime = $this->request->post('endtime');
      if(!$endtime){
          $endtime = date('Y-m-d H:i:s');
      }
      $apptype = $this->request->post('apptype');
      if(!$apptype){
        $this->error(__('Missed parameters'));
      }
      $appname = $this->request->post('appname');
      if(!$appname){
        $this->error(__('Missed parameters'));
      }
      $name_type = $this->get_apps('name_type');
      $is_valid_app = $this->has_app($appname, $apptype, $name_type);
      if(!$is_valid_app){
          $this->error(__('Invalid parameters'));
      }

      $action = isset(config('type_action')[$apptype]) ? config('type_action')[$apptype] : '';
      // dump(config('type_action'));exit;
      $type = isset(config('actions')[$action]) ? config('actions')[$action] : '';
      if(!$action || !$type){
        $this->error('未知的类型');
      }
      $targetName = $appname;

      $mission = $this->getUserConfig();
      $missionIds = array();
      $missionIds_str = '';
      foreach ($mission as $key => $value) {
        if($type == $key){
          foreach ($value as $key2 => $value2) {
              $missionIds[] = trim($value2['missionid']);
              $missionIds_str .= '{
                  "match_phrase": {
                    "missionId": {
                      "query": "'.trim($value2['missionid']).'"
                    }
                  }
                },';
          }
        }
      }
      //去掉最后一个逗号
      if($missionIds_str){
        $missionIds_str = substr($missionIds_str, 0, strlen($missionIds_str)-1);
      }

      $agg_str = '';
      if($action == 'get_QualityVideoResult_FW'){
        $agg_arr = array(
          "videoSpeed",
          "videoBufferTime",
          "videoBufferNumber",
          "videoFirstFrameTime"
        );
      }else if($action == 'get_QualityFileDownloadResult_FW'){
        $agg_arr = array(
          "httpFirstPacketTime",
          "totalOpenTime",
          "dnsDelay",
          "tcpBuildLinkDelay",
          "elementSuccessRate",
          "fileDownloadSpeed"
        );
      }else if($action == 'get_QualityWebpageResult_FW'){ 
        $agg_arr = array(
          "httpFirstPacketTime",
          "totalOpenTime",
          "firstPaint",
          "dnsDelay",
          "tcpBuildLinkDelay",
          "elementSuccessRate",
          "webpageDownloadSpeed"
        );
      }else if($action == 'get_QualityLinkRouteResult_FW'){
        $agg_arr = array(
          "netWorkDelay",
          "maxWorkDelay",
          "minWorkDelay",
          "equipmentSuccessRate",
          "shaking"
        );
      }
      $agg_str = '';
      foreach ($agg_arr as $key => $value) {
        $agg_str .= ',
            "'.$value.'": {
              "avg": {
                "field": "'.$value.'"
              }
            }';
      }
      $starttime_es = strtotime($starttime).'000';
      $endtime_es = strtotime($endtime).'000';
      $data_string = '{
          "aggs": {
            "qualityScore": {
              "avg": {
                "field": "qualityScore"
              }
            }'.$agg_str.' 
          },
          "size": 1,
          "_source": {
            "excludes": []
          },
          "stored_fields": [
            "*"
          ],
          "script_fields": {},
          "docvalue_fields": [],
          "query": {
            "bool": {
              "must": [
                {
                  "match_all": {}
                },
                {
                  "range": {
                    "testTime": {
                      "gte": '.$starttime_es.',
                      "lte": '.$endtime_es.',
                      "format": "epoch_millis"
                    }
                  }
                }
                ,{
                  "match_phrase": {
                    "action": {
                      "query": "'.$action.'"
                    }
                  }
                },{
                  "match_phrase": {
                    "targetName": {
                      "query": "'.$appname.'"
                    }
                  }
                }
              ],
              "filter": [{
                "range": {
                  "qualityScore": {
                    "gt": "0"
                  }
                }
              }],
              "should": [
                '.$missionIds_str.'
              ],
              "minimum_should_match": 1,
              "must_not": []
            }
          }
        }';
        $result = $this->request_nqm($data_string, 'all');
        //把null的返回改为-1
        // dump($result);exit;
        $result = $this->formatNullData($result, $action);
        $this->success('成功', $result);
    }
    public function formatNullData($result, $action){
      $arr = array();
      $arr['testTarget'] = isset($result['hits']['hits'][0]['_source']['testTarget']) ? $result['hits']['hits'][0]['_source']['testTarget'] : '';
      if($action == 'get_QualityVideoResult_FW'){
        $arr['isBlack'] = isset($result['hits']['hits'][0]['_source']['isBlack']) ? $result['hits']['hits'][0]['_source']['isBlack'] : -1;
        $arr['targetLocation'] = '';
        if(isset($result['hits']['hits'][0]['_source']['target_location'])){
          $tl = $result['hits']['hits'][0]['_source']['target_location'];
          $arr['targetLocation'] = $tl['country'].$tl['region'].$tl['city'].$tl['ISP'];
        }
      }
      foreach ($result['aggregations'] as $key => $value) {
        $arr[$key] = ($value['value']) ? round($value['value'],2) : -1;
      }
      return $arr;
    }

    //所有应用的，时延、丢包、抖动 TODO 新版已没有该功能
    public function all_app_detail(){
      $this->error('该接口已停止使用');
    }
    //这里只要配置在白名单里应用，返回的应用不是全要
    public function getDbAppScore($all_score){
        $score = array();
        $keys = array_keys($all_score);
        $rs = Db::name('app')->field('name')->where('name','in',$keys)->order('sort desc')->select();
        foreach ($rs as $key => $value) {
            $score[] = $all_score[$value['name']];
        }
        return $score;
    }
    //应用名可以相同，所以不能以应用名为键值
    public function get_type_icon($appname, $flag, $name_type){
        foreach ($name_type as $key => $value) {
            if($value['name'] == $appname){
                if($flag == 'type'){
                    return $value['type'];
                }else if($flag == 'icon'){
                    return $value['icon'];
                }
            }
        }
        return '';
    }
    public function format_sort($data){
        $return_arr = array();
        $keys = array_keys($data);
        $rs = Db::name('app_type')->field('name,id')->where('name','in',$keys)->order('sort desc')->select();
        // dump($rs);exit;
        foreach ($rs as $key => $value) {
            $apps = array();
            $app_rs = Db::name('app')->field('name')->where('app_type_id', $value['id'])->where('name', 'in',array_keys($data[$value['name']]))->order('sort desc')->select();
            foreach ($app_rs as $key2 => $value2) {
                $apps[$value2['name']] = $data[$value['name']][$value2['name']];
            }
            $return_arr[$value['name']] = $apps;
        }
        return $return_arr;
    }
    public function has_app($appname, $apptype, $name_type){
        foreach ($name_type as $key => $value) {
            if($value['name'] == $appname && $value['type'] == $apptype){
                return true;
            }
        }
        return false;
    }
    public function apps(){
        $rs = Db::name('app')
        ->alias('a')
        ->field('a.name,t.name as type')
        ->join('app_type t', 'a.app_type_id = t.id', 'left')
        ->select();
        $rs2 = array();
        foreach ($rs as $key => $value) {
            $rs2[$value['type']][] = $value['name']; 
        }
        $data_arr = array();
        foreach ($rs2 as $type => $value) {
            $item = array();
            $item['name'] = $type;
            foreach ($value as $key2 => $value2) {
                $item['list'][] = $value2;
            }
            $data_arr[] = $item;
        }
        $this->success('成功', $data_arr);
    }
    public function apptype($name){
      $rs = Db::name('app_type')->field('icon')->where('name', $name)->find();
      if($rs){
        return $rs['icon'];
      }else{
        return '';
      }
    }
}
